package com.faner4cloud.yun.controller;

import cn.hutool.json.JSONUtil;
import com.faner4cloud.yun.common.exception.BizException;
import com.faner4cloud.yun.common.redis.RedisLock;
import com.faner4cloud.yun.common.redis.cache.RedisCache;
import com.faner4cloud.yun.common.util.R;
import com.faner4cloud.yun.common.util.RateLimitUtil;
import com.faner4cloud.yun.coustom.BaseConsumer;
import com.faner4cloud.yun.coustom.KafkaAtaOpsDto;
import com.faner4cloud.yun.coustom.KafkaBaseDto;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.MessageFormat;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @作者 Faner
 * @创建时间 2022/2/9 17:27
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(value = "test", tags = "测试")
@ApiSupport(order = 1)
public class TestController {

	private final BaseConsumer baseConsumer;
	private final RedisLock redisLock;
	private final RedisCache redisCache;



	@ApiOperation(value = "three", notes = "three")
	@ApiOperationSupport(order = 30, author = "")
	@GetMapping("/test/three")
	public R three() {
		KafkaBaseDto kafkaBaseDto = new KafkaBaseDto();
		kafkaBaseDto.setType(1);

		KafkaAtaOpsDto kafkaAtaOpsDto = new KafkaAtaOpsDto();
		kafkaAtaOpsDto.setOpsType(1);
		kafkaAtaOpsDto.setDataDetail("2222");

		kafkaBaseDto.setData(JSONUtil.toJsonStr(kafkaAtaOpsDto));
		baseConsumer.onConsumer(JSONUtil.toJsonStr(kafkaBaseDto));

		return R.ok();
	}

	@ApiOperation(value = "two", notes = "two")
	@ApiOperationSupport(order = 10, author = "")
	@GetMapping("/test/four")
	public void four() {
		CompletableFuture.runAsync(()-> {
			log.info("开始了");
			throw new BizException("嗨");
		}).exceptionally(e -> {
				log.error("这里异常了", e);
			String format = MessageFormat.format("您操作的 {0} 异常，请稍候重试。", "999");
			return null;
			}).thenRun(()->log.info("结束了哈"));
	}

	private final RateLimitUtil signUpSignalRateLimit;

	@GetMapping("/test/five")
	public void four1() {
		//模拟6个人
		for (int i = 1; i <= 1000; i++) {
			new Thread(() -> {
				try {

					System.out.println(Thread.currentThread().getName() + "开始了");
					Assert.isTrue(signUpSignalRateLimit.tryAcquire(), "报名太火爆，请稍后重试");
					TimeUnit.SECONDS.sleep(2);
					System.out.println(Thread.currentThread().getName() + "结束了");
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					//释放，会将当前的信号量释放+1，然后唤醒
					signUpSignalRateLimit.release();
				}
				}, String.valueOf(i)).start();
		}
	}

	@GetMapping("/test/redis/lock")
	public void redisLock(@RequestParam Long lockId) {
		String key = "qg:"+lockId;
		try {
			boolean lock = redisLock.tryLock(key, 60L);
			if (!lock){
				System.out.println(Thread.currentThread().getName()+"未获取到锁");
				return ;
			}
			Integer capacity = (Integer) redisCache.get("capacity");
			if (capacity < 1){
				System.out.println(Thread.currentThread().getName()+"容量不足");
				return;
			}
			redisCache.decrBy("capacity",1L);
			System.out.println(Thread.currentThread().getName()+"获取座位");
		} catch (InterruptedException e) {
			log.error("线程异常",e);
			Thread.currentThread().interrupt();
		}finally {
			redisLock.unlock(key);
		}

	}

}
